SpringAI - Prompt(一)
Message
AI提示词
- 提示词是引导AI进行特定的处理及生成的输入,高效的提示词可以显著提升AI的处理及响应。
- 这里要记录的并不是提示词深入的概念,也不是如何设计高效的提示词,最起码首要目标不是这些。
- 而是学习和记录如何使用SpringAI提供的API快速的、灵活的将提示词编入程序与AI进行交互。
- 其实早在入门篇中就已经记录到了,且在过去的案例里面也基本都是用到了,不过都相对简单。
回顾前面的案例
ChatClient
在学习SpringAI记录的第一个案例中(如下)我们就已经使用到了提示词
1
2
3
4// 创建一个 client
ChatClient chatClient = ChatClient.create(chatModel);
// 调用 deepseek
String content = chatClient.prompt().system(SYSTEM_PROMPT).user(userMessage).call().content();使用
ChatClient
在调用call()
方法之前就通过设置system、user
消息作为提示词来与AI交互。通过简单查看源码发现最后是创建了
SystemMessage
和UserMessage
Advisor
还有在记录
Advisor(三)
中的“提示词增强”的PromptEnhancementExampleAdvisor
中使用到的如下代码。1
2
3chatClientRequest.prompt()
.augmentSystemMessage(systemMessage -> SystemMessage.builder().text(sysMsg).build())
.augmentUserMessage(userMessage -> UserMessage.builder().text(String.format(userTemplate, userMessage.getText())).build())上面的Code是通过
ChatClientRequest
对system、user
消息进行修改/增强后作为新的提示词与AI交互。这里也是使用的
SystemMessage
和UserMessage
来创建新的消息
Message家族
Message族谱
下面是官方的类图
从类图中可以看到被分成来消息
Message
和多媒体MediaContent
两块,这里主要以Message
为主,多媒体后续可能会在多模态继续记录到。Message
又通过MessageType
来定义了四类角色的消息,除了已经接触到的system、user
,还有assistant、tool(function)
。- system:用于表示向AI设定规则指令的输入。比如要求AI按指定结构输出的规则指令。还有比如要求AI是
Java专家、小朋友科普老师
等一些拟人行为的规则指令。 - user:用于表示用户需求的输入。比如提问、要求AI处理或生成内容等需求性指令。
- assistant:用于给AI作为上下文辅助的输入。
- 比如与AI历史的对话内容确保AI的处理是在一个已有的上下文中进行;
- 还有就是如果交互包含工具调用,那么在工具调用后补充内容给AI时需要将工具信息添加在
assistant
消息中,再结合tool
消息共同使用。
- tool(function):用于结合
assistant
消息一起将工具调用后的内容补充给AI的输入。(工具调用具体后面会继续学习记录)
- system:用于表示向AI设定规则指令的输入。比如要求AI按指定结构输出的规则指令。还有比如要求AI是
案例1
先使用
system、user
消息与AI正常交互,再使用assistant
消息结合上下文1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23private final ChatClient promptClient;
public void assistantExample() {
log.info("\n=======================================第一次与AI正常交互=======================================");
Prompt prompt = Prompt.builder()
.messages(
// 用英文作为系统提示词
SystemMessage.builder().text("You are a Java expert").build(),
// 用户输入了Deque类,默认也是英文
UserMessage.builder().text("java.util.Deque").build()
).build();
String content = promptClient.prompt(prompt).call().content();
log.info("\n=======================================第二次结合上下文交互=======================================");
Prompt assistantPrompt = Prompt.builder()
.messages(
// 用户再次要求使用中文输出
UserMessage.builder().text("中文").build(),
// 并将上一次的输出内容添加在assistant消息作为上下文
new AssistantMessage(content)
).build();
promptClient.prompt(assistantPrompt).call().content();
}第一次交互结果,可以看到都是英文输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
202025-07-01T17:25:52.824+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.prompt.PromptClientExample :
=======================================第一次与AI正常交互=======================================
2025-07-01T17:25:52.876+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
Chat client request to AI
prompt text -> You are a Java expertjava.util.Deque
context -> {
"ClientName" : "promptClient"
}
2025-07-01T17:26:36.162+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
Chat client response from AI
output text -> # `java.util.Deque` Interface in Java
The `Deque` (pronounced "deck") interface in Java represents a double-ended queue, which is a linear collection that supports element insertion and removal at both ends. It extends the `Queue` interface and is part of the Java Collections Framework.
## Key Features
- **Double-ended operations**: Supports insertion, removal, and examination at both head and tail
- **Capacity-restricted implementations**: Some implementations (like `ArrayDeque`) have fixed size limits
- **Null elements**: Most implementations don't allow null elements
- **Not thread-safe**: Requires external synchronization for concurrent access第二次交互结果输出的部分就全是中文了,并且这次的提示词是包含第一次输出的英文结果的(就是
AssistantMessage
)。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
262025-07-01T17:26:36.165+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.prompt.PromptClientExample :
=======================================第二次结合上下文交互=======================================
2025-07-01T17:26:53.887+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
Chat client request to AI
prompt text -> 中文# `java.util.Deque` Interface in Java
The `Deque` (pronounced "deck") interface in Java represents a double-ended queue, which is a linear collection that supports element insertion and removal at both ends. It extends the `Queue` interface and is part of the Java Collections Framework.
## Key Features
- **Double-ended operations**: Supports insertion, removal, and examination at both head and tail
- **Capacity-restricted implementations**: Some implementations (like `ArrayDeque`) have fixed size limits
- **Null elements**: Most implementations don't allow null elements
- **Not thread-safe**: Requires external synchronization for concurrent access
2025-07-01T17:27:40.511+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
Chat client response from AI
output text -> # Java中的`java.util.Deque`接口
`Deque`(发音为"deck")是Java中的双端队列接口,它代表了一个支持在两端插入和移除元素的线性集合。它扩展了`Queue`接口,是Java集合框架的一部分。
## 核心特性
- **双端操作**:支持在头部和尾部进行插入、移除和检查操作
- **容量限制**:某些实现(如`ArrayDeque`)有固定大小限制
- **空元素**:大多数实现不允许null元素
- **非线程安全**:需要外部同步来实现并发访问
案例2
在与AI交互的时候,可能会用到工具调用来增强AI的能力。这时候与AI交互的过程中就需要用到
assistant
和tool
两个角色的消息了。这里简单模拟一个工具调用的案例,然后大概看看SpringAI是如何将工具调用的结果补充给AI的。
创建一个模拟获取天气的工具类,写死返回张家界的天气信息。(这里不做过多记录,后面会专门学习工具调用)
1
2
3
4
5
6public class MockGetWeather {
public String mockGetWeather( { String location)
return "{\"location\":{\"name\":\"张家界\",\"path\":\"中国, 湖南, 张家界\"},\"now\":{\"precipitation\":0,\"temperature\":31.5,\"pressure\":1005,\"humidity\":43,\"windDirection\":\"西南风\",\"windDirectionDegree\":216,\"windSpeed\":2.7,\"windScale\":\"微风\",\"feelst\":23.1}}";
}
}添加工具调用
1
2
3
4
5
6
7
8
9
10
11public void toolExample() {
String content = promptClient.prompt()
// 这里只是做了一层封装,与 SystemMessage.builder() 是一样的,底层还是用的 SystemMessage
.system("你是一个万能的小助手")
// 这里也是封装了,底层是 UserMessage
.user("帮我查询张家界今天天气如何?")
// 添加工具调用
.tools(new MockGetWeather())
.call()
.content();
}调用结果。是可以看到这些天气数据是与模拟天气工具中返回的数据是一致的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
212025-07-01T18:31:26.544+08:00 INFO 14325 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
Chat client request to AI
prompt text -> 你是一个万能的小助手帮我查询张家界今天天气如何?
context -> {
"ClientName" : "promptClient"
}
2025-07-01T18:31:37.199+08:00 INFO 14325 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
Chat client response from AI
output text -> 张家界今天的天气情况如下:
- **温度**: 31.5°C
- **体感温度**: 23.1°C
- **降水概率**: 0%
- **气压**: 1005 hPa
- **湿度**: 43%
- **风向**: 西南风(216°)
- **风速**: 2.7 m/s(微风)
天气晴朗,适合出行!
context -> {ClientName=promptClient}
简单看了一下SpringAI与AI交互的过程,下图就是执行工具的大概过程,可以看到其实就是使用
AssistantMessage
和ToolResponseMessage
。
总结
- 可以通过提示词来约束、要求AI按照特定的规则处理及生成;也可以显著提升、增强AI的处理能力。
- SpringAI与AI交互的提示词主要是通过
Message
来实现结构化。 - 四类角色的
Message
分别在不同的角度使用提示词来增强AI的能力。 - 工具调用的消息是需要
AssistantMessage
和ToolResponseMessage
结合使用的,否则可能会报错。
最后
- 工具调用相关的后续会继续学习记录如何使用。
- SpringAI还提供了提示词更多的操作在下一篇继续记录,如提示词模版。
- 所有案例的源码,都会提交在GitHub上。包:
com.spring.ai.example.prompt.one